#nullable enable

using System;
using System.Collections.Generic;
using System.Globalization;
using System.Threading.Tasks;
using PHMEE.CommonUtils;
using PHMEE.Localization;
using Volo.Abp;
using Volo.Abp.Application.Dtos;

namespace PHMEE.EnergyEfficiency.ShaftPowerMeter;

public class ShaftPowerMeterAppService : PHMEEAppService, IShaftPowerMeterAppService
{
    private readonly IPHMEETimeProvider _phmeeTimeProvider;
    private readonly IShaftPowerMeterTdRepository _shaftPowerMeterTdRepository;

    public ShaftPowerMeterAppService(IPHMEETimeProvider phmeeTimeProvider, IShaftPowerMeterTdRepository shaftPowerMeterTdRepository)
    {
        LocalizationResource = typeof(EnergyEfficiencyResource);
        
        _phmeeTimeProvider = phmeeTimeProvider;
        _shaftPowerMeterTdRepository = shaftPowerMeterTdRepository;
    }

    private readonly List<string> _shaftPowerMeterDescList =
    [
        ShaftPowerMeterAppServiceUtils.ShaftSpeed,
        ShaftPowerMeterAppServiceUtils.ShaftTorque,
        ShaftPowerMeterAppServiceUtils.ShaftPower,
        ShaftPowerMeterAppServiceUtils.TotalRevolutions,
        ShaftPowerMeterAppServiceUtils.TotalEnergy
    ];
    
    // // 获取实时轴功率计采集数据
    // public async Task<List<ShaftPowerMeterDto>> GetRealtimeShaftPowerMeterDataAsync(Guid vesselId)
    // {
    //     var utcNow = _phmeeTimeProvider.GetUtcNow();
    //
    //     // 防止数据同步延迟导致不显示数据，所以时间范围放宽到一小时
    //
    //     // TODO: 在没有实际数据时，先往前查一个月，查到所有测试数据，发版时需调整
    //     var startTime = utcNow.AddMonths(-1);
    //
    //     // 查询 shaft_power_meter 超级表下的每一张子表中的 utcNow 之前的最新一条数据，带 Tags
    //     var shaftPowerMeters =
    //         await _shaftPowerMeterTdRepository.GetLatestOrDefaultByDateTimeCloseCloseAsync(vesselId, startTime, utcNow);
    //
    //     if (shaftPowerMeters == null)
    //     {
    //         return [];
    //     }
    //
    //     List<ShaftPowerMeterDto> result = [];
    //
    //     foreach (var shaftPowerMeterDesc in _shaftPowerMeterDescList)
    //     {
    //         result.Add(new ShaftPowerMeterDto
    //         {
    //             Ts = shaftPowerMeters.Ts,
    //             Desc = shaftPowerMeterDesc,
    //             V = ShaftPowerMeterAppServiceUtils.GetValueByDesc(shaftPowerMeters, shaftPowerMeterDesc),
    //             U = ShaftPowerMeterAppServiceUtils.GetUnitByDesc(shaftPowerMeterDesc),
    //         });
    //     }
    //
    //     return result;
    // }

    public List<string> GetDescriptions(Guid vesselId)
    {
        return _shaftPowerMeterDescList;
    }

    // 查询轴功率计数据
    public async Task<PagedResultDto<ShaftPowerMeterDto>> GetShaftPowerMeterDataAsync(Guid vesselId,
        string? description, DateTime startDateTime, DateTime endDateTime, int skipCount, int maxResultCount)
    {
        if (string.IsNullOrWhiteSpace(description))
        {
            throw new UserFriendlyException(L[PHMEEEnergyEfficiencyErrorCodes.TagDescriptionCannotBeEmpty],
                PHMEEEnergyEfficiencyErrorCodes.TagDescriptionCannotBeEmpty);
        }

        description = description.Trim();

        var (totalCount, shaftPowerMeters) =
            await _shaftPowerMeterTdRepository.GetListByDateTimeAsync(vesselId, startDateTime, endDateTime, skipCount, maxResultCount);
        
        List<ShaftPowerMeterDto> result = [];
        
        foreach (var shaftPowerMeter in shaftPowerMeters)
        {
            foreach (var shaftPowerMeterDesc in _shaftPowerMeterDescList)
            {
                // 根据 description 查询，只返回对应 description 的数据
                if (shaftPowerMeterDesc.ToLower() == description.Trim().ToLower())
                {
                    result.Add(new ShaftPowerMeterDto
                    {
                        Ts = shaftPowerMeter.Ts,
                        Desc = shaftPowerMeterDesc,
                        V = ShaftPowerMeterAppServiceUtils.GetValueByDesc(shaftPowerMeter, description),
                        U = ShaftPowerMeterAppServiceUtils.GetUnitByDesc(description),
                    });
                }
            }
        }
        
        return new PagedResultDto<ShaftPowerMeterDto>(totalCount, result);
    }
    
    /// <summary>
    /// 获取最新轴功率计采集数据
    /// </summary>
    /// <param name="vesselId"></param>
    /// <returns></returns>
    public async Task<List<ShaftPowerMeterDto>> GetLatestShaftPowerMeterDataAsync(Guid vesselId)
    {
        var utcNow = _phmeeTimeProvider.GetUtcNow();

        // 查询 shaft_power_meter 超级表下的每一张子表中的 utcNow 之前的最新一条数据，带 Tags
        var shaftPowerMeter =
            await _shaftPowerMeterTdRepository.GetLatestOrDefaultByDateTimeAsync(vesselId, utcNow);

        if (shaftPowerMeter is null)
        {
            return [];
        }

        List<ShaftPowerMeterDto> result = [];

        foreach (var shaftPowerMeterDesc in _shaftPowerMeterDescList)
        {
            result.Add(new ShaftPowerMeterDto
            {
                Ts = shaftPowerMeter.Ts,
                Desc = shaftPowerMeterDesc,
                V = ShaftPowerMeterAppServiceUtils.GetValueByDesc(shaftPowerMeter, shaftPowerMeterDesc),
                U = ShaftPowerMeterAppServiceUtils.GetUnitByDesc(shaftPowerMeterDesc),
            });
        }

        return result;
    }
}

public static class ShaftPowerMeterAppServiceUtils
{
    // Descriptions
    public const string ShaftSpeed = "SHAFT SPEED";
    public const string ShaftTorque = "SHAFT TORQUE";
    public const string ShaftPower = "SHAFT POWER";
    public const string TotalRevolutions = "TOTAL REVOLUTIONS";
    public const string TotalEnergy = "TOTAL ENERGY";

    public static string GetUnitByDesc(string desc)
    {
        return desc switch
        {
            ShaftSpeed => "rpm",
            ShaftTorque => "kNm",
            ShaftPower => "kW",
            TotalRevolutions => "revolutions",
            TotalEnergy => "kWh",
            _ => ""
        };
    }

    public static string GetValueByDesc(ShaftPowerMeterTde shaftPowerMeterTde, string desc)
    {
        string value =  desc switch
        {
            ShaftSpeed => shaftPowerMeterTde.Speed.ToString("F2", CultureInfo.InvariantCulture),
            ShaftTorque => shaftPowerMeterTde.Torque.ToString("F2", CultureInfo.InvariantCulture),
            ShaftPower => shaftPowerMeterTde.Power.ToString("F2", CultureInfo.InvariantCulture),
            TotalRevolutions => shaftPowerMeterTde.TotalRevs.ToString("F0", CultureInfo.InvariantCulture),
            TotalEnergy => shaftPowerMeterTde.TotalEng.ToString("F0", CultureInfo.InvariantCulture),
            _ => "0"
        };
        
        return value;
    }
}